/**
 * 
 */
package com.fita.entity.wallet;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.springframework.format.annotation.DateTimeFormat;
import com.demo2do.core.utils.DateFormatUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fita.entity.agent.Agent;
import com.fita.entity.order.OrderPayType;
import com.fita.entity.principal.Principal;

/**
 *  充值记录
 * @author Guangli Yan
 *
 */
@Entity
@Table(name = "recharge_record")
public class RechargeRecord {

    @Id
    @GeneratedValue
    private Long id;
    
    /**
     * 充值订单号
     */
    private String code;
    
    /**
     * 充值金额（分）
     */
    private Integer amount;

    /**
     * 当前余额（分）
     */
    private Integer currentUserWalletAmount;

    /**
     * 实际支付金额(分)
     */
    private Integer actualPayAmount;
    
    /**
     * 状态
     */
    @Enumerated(EnumType.STRING)
    private RechargeRecordStatus status;

    /**
     * 支付方式
     */
    @Enumerated(EnumType.STRING)
    private OrderPayType payType;

    /**
     * 支付流水号
     */
    private String payCode;

    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date payTime;
    
    /**
     * 目标钱包
     */
    @ManyToOne
    @JoinColumn(nullable = false)
    @JsonIdentityInfo(generator= ObjectIdGenerators.PropertyGenerator.class, property="id")
    @JsonIdentityReference(alwaysAsId=true)
    private UserWallet targetWallet;

    @ManyToOne
    private Agent operator;

    @ManyToOne
    private Principal operatePrincipal;

    private Date createTime;
    
    @Column(name = "is_disabled")
    private Boolean disabled;

    /**
     * the default constructor
     */
    public RechargeRecord() {
    }

    /**
     *
     * @param wallet
     * @param amount
     * @param operator
     */
    public RechargeRecord(UserWallet wallet, Integer amount, Agent operator) {
        this.code = "R" + new Date().getTime();
        this.targetWallet = wallet;
        this.amount = amount;
        this.status = RechargeRecordStatus.UNPAID;
        this.createTime = new Date();
        this.disabled = false;
        this.operator = operator;
    }

    /**
     *
     * @param wallet
     * @param amount
     */
    public RechargeRecord(UserWallet wallet, Integer amount){
        this.code = "R" + new Date().getTime();
        this.targetWallet = wallet;
        this.amount = amount;
        this.status = RechargeRecordStatus.UNPAID;
        this.createTime = new Date();
        this.disabled = false;
    }


    /**
     * 支付
     * @param amount
     * @param payType
     * @return
     */
    public RechargeRecord paid(int amount, OrderPayType payType, String payCode, Integer userWalletAmount) {

        this.actualPayAmount = amount;

        this.status = RechargeRecordStatus.PAID;

        this.payType = payType;

        this.payTime = new Date();

        this.payCode = payCode;

        this.currentUserWalletAmount = userWalletAmount;

        return this;
    }

    /**
     * 线下充值
     * @param amount
     * @param payType
     * @param payCode
     * @param operatePrincipal
     * @param userWalletAmount
     * @return
     */
    public RechargeRecord offlineRechargePaid(int amount, OrderPayType payType, String payCode, Principal operatePrincipal, Integer userWalletAmount) {

        this.actualPayAmount = amount;

        this.status = RechargeRecordStatus.PAID;

        this.payType = payType;

        this.payTime = new Date();

        this.payCode = payCode;

        this.operatePrincipal = operatePrincipal;

        this.currentUserWalletAmount = userWalletAmount;

        return this;
    }

    /**
     * 转换成人民币格式
     * @return
     */
    @Transient
    public BigDecimal getCnyAmount(){

        if (amount != null && amount > 0){
            return new BigDecimal(amount).divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
        }
        return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 获取当时交易前钱包余额
     * @return
     */
    @Transient
    public BigDecimal getCnyCurrentUserWalletAmount(){
        if (currentUserWalletAmount != null && currentUserWalletAmount > 0){
            return new BigDecimal(currentUserWalletAmount).divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP);
        }
        return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 格式化创建时间
     * @return
     */
    @Transient
    public String getFormatedCreateTime(){return DateFormatUtils.format(this.createTime); }


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public Integer getAmount() {
        return amount;
    }

    public void setAmount(Integer amount) {
        this.amount = amount;
    }

    public UserWallet getTargetWallet() {
        return targetWallet;
    }

    public void setTargetWallet(UserWallet targetWallet) {
        this.targetWallet = targetWallet;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Boolean getDisabled() {
        return disabled;
    }

    public void setDisabled(Boolean disabled) {
        this.disabled = disabled;
    }

    public OrderPayType getPayType() {
        return payType;
    }

    public void setPayType(OrderPayType payType) {
        this.payType = payType;
    }

    public Date getPayTime() {
        return payTime;
    }

    public void setPayTime(Date payTime) {
        this.payTime = payTime;
    }

    public RechargeRecordStatus getStatus() {
        return status;
    }

    public void setStatus(RechargeRecordStatus status) {
        this.status = status;
    }

    public Agent getOperator() {
        return operator;
    }

    public void setOperator(Agent operator) {
        this.operator = operator;
    }

    public String getPayCode() {
        return payCode;
    }

    public void setPayCode(String payCode) {
        this.payCode = payCode;
    }

    public Integer getActualPayAmount() {
        return actualPayAmount;
    }

    public void setActualPayAmount(Integer actualPayAmount) {
        this.actualPayAmount = actualPayAmount;
    }

    public Principal getOperatePrincipal() {
        return operatePrincipal;
    }

    public void setOperatePrincipal(Principal operatePrincipal) {
        this.operatePrincipal = operatePrincipal;
    }

    public Integer getCurrentUserWalletAmount() {
        return currentUserWalletAmount;
    }

    public void setCurrentUserWalletAmount(Integer currentUserWalletAmount) {
        this.currentUserWalletAmount = currentUserWalletAmount;
    }
}
